﻿using System;
using System.Threading;
using Domain.Abstract;
using System.Diagnostics;
using Domain.Abstract.Interfaces;

namespace Domain.Entities
{
    public class ID
    {
        public Guid outterGuid { get; private set; }
        public string CheckerType { get; private set; }
        public string Port { get; private set; }
        public ID(Guid outterGuid, string CheckerType, string Port)
        {
            this.outterGuid = outterGuid;
            this.CheckerType = CheckerType;
            this.Port = Port;
        }
        public override string ToString()
        {
            return String.Format("{0}-{1}-{2}", outterGuid, CheckerType, Port);
        }
    }
    public class AsyncCheckinger
    {
        public ID Id { get; private set; }
        int delay;
        IChecker checker;
        bool loop = false;
        CheckerResult result;
        private readonly Object _lock = new object();

        // TODO !!!!! убрать бесконечную петлю http://stackoverflow.com/questions/7402146/cpu-friendly-infinite-loop
        public AsyncCheckinger(ID id, int delay, IChecker checker)
        {
            this.Id = id;
            this.delay = delay;
            this.checker = checker;
        }
        void run(Object ob)
        {
            lock (_lock)
            {
                result = null;
                Thread th = new Thread(() =>
                {
                    result = checker.Check();
                    checkLoop();
                });
                th.Start();
                while (result == null)
                {
                    th.Join(10);
                }
                result.writeToDb(this.Id.outterGuid);
            }
        }
        public void Run()
        {
            Console.WriteLine(">>> STARTED: {0}", Id.ToString());
            loop = true;
            ThreadPool.QueueUserWorkItem(new WaitCallback(run));
        }
        private void checkLoop()
        {
            if (loop)
            {
                Thread.Sleep(delay);
                run(null);
            }
            else
            {
                Console.WriteLine(">>> STOPED: {0}", Id.ToString());
            }
        }
        public void Stop()
        {
            loop = false;
        }
    }
}
